package com.tbynet.jwp.framework.kit;

import com.jfinal.kit.StrKit;

import java.text.Normalizer;
import java.util.regex.Pattern;

public class SlugKit {

    /** 用于匹配非字母数字字符的正则表达式 */
    private static final Pattern NON_ALPHANUMERIC = Pattern.compile("[^a-zA-Z0-9\\s]");

    /** 用于匹配连续空格的正则表达式 */
    private static final Pattern MULTIPLE_SPACES = Pattern.compile("\\s+");

    /** 用于匹配连续连字符的正则表达式 */
    private static final Pattern MULTIPLE_DASHES = Pattern.compile("-+");


    /**
     * 将字符串转换为URL友好的slug格式
     *
     * 转换规则：
     * 1. 转换为小写
     * 2. 移除重音符号
     * 3. 移除非字母数字字符（保留空格）
     * 4. 将空格替换为连字符
     * 5. 移除首尾的连字符
     * 6. 合并连续的连字符
     *
     * @param input 输入字符串
     * @return URL友好的slug
     */
    public static String slugify(String input) {
        if (StrKit.isBlank(input)) {
            return "";
        }

        // 转换为小写
        String slug = input.toLowerCase();

        // 移除重音符号（将é转换为e等）
        slug = removeAccents(slug);

        // 移除非字母数字字符，但保留空格
        slug = NON_ALPHANUMERIC.matcher(slug).replaceAll("");

        // 将空格替换为连字符
        slug = slug.replaceAll("\\s+", "-");

        // 合并连续的连字符
        slug = MULTIPLE_DASHES.matcher(slug).replaceAll("-");

        // 移除首尾的连字符
        slug = slug.replaceAll("^-|-$", "");

        return slug;
    }

    /**
     * 移除字符串中的重音符号
     *
     * @param input 输入字符串
     * @return 移除重音符号后的字符串
     */
    private static String removeAccents(String input) {
        if (StrKit.isBlank(input)) {
            return input;
        }

        try {
            // 使用Normalizer分解重音字符
            String normalized = Normalizer.normalize(input, Normalizer.Form.NFD);

            // 移除组合标记（重音符号）
            Pattern pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
            return pattern.matcher(normalized).replaceAll("");
        } catch (Exception e) {
            // 如果Normalizer失败，返回原始输入
            return input;
        }
    }

    /**
     * 生成唯一的slug，如果已存在则添加数字后缀
     *
     * @param baseSlug 基础slug
     * @param existsChecker 存在性检查器
     * @return 唯一的slug
     */
    public static String generateUniqueSlug(String baseSlug, SlugExistsChecker existsChecker) {
        if (StrKit.isBlank(baseSlug)) {
            return "";
        }

        String slug = baseSlug;
        int counter = 1;

        // 检查是否唯一，如果不唯一则添加数字后缀
        while (existsChecker != null && existsChecker.exists(slug)) {
            slug = baseSlug + "-" + counter;
            counter++;
        }

        return slug;
    }

    /**
     * slug存在性检查接口
     */
    @FunctionalInterface
    public interface SlugExistsChecker {
        boolean exists(String slug);
    }
}
